# Author: zhaozeliang
# Date: 2025-09-06

from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.utils import timezone
from django.db.models import Q
from .models import RiskIndicator, RiskAlert, RiskAssessmentResult, RiskLimit, RiskMonitoringTask
from .serializers import (
    RiskIndicatorSerializer, RiskAlertSerializer, RiskAssessmentResultSerializer,
    RiskLimitSerializer, RiskMonitoringTaskSerializer
)
from .services import RiskCalculationService, RiskMonitoringService
from admin_management.permissions import IsAdminUser


class RiskIndicatorViewSet(viewsets.ModelViewSet):
    """
    风险指标管理视图集
    """
    queryset = RiskIndicator.objects.all()
    serializer_class = RiskIndicatorSerializer
    permission_classes = [IsAuthenticated, IsAdminUser]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        is_active = self.request.query_params.get('is_active')
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')
        return queryset


class RiskAlertViewSet(viewsets.ModelViewSet):
    """
    风险预警管理视图集
    """
    queryset = RiskAlert.objects.all()
    serializer_class = RiskAlertSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user = self.request.user
        
        # 普通用户只能查看自己的投资组合的预警
        if not user.is_staff:
            queryset = queryset.filter(portfolio__user=user)
        
        # 过滤参数
        alert_level = self.request.query_params.get('alert_level')
        status_filter = self.request.query_params.get('status')
        portfolio_id = self.request.query_params.get('portfolio_id')
        
        if alert_level:
            queryset = queryset.filter(alert_level=alert_level)
        if status_filter:
            queryset = queryset.filter(status=status_filter)
        if portfolio_id:
            queryset = queryset.filter(portfolio_id=portfolio_id)
            
        return queryset
    
    @action(detail=True, methods=['post'])
    def resolve(self, request, pk=None):
        """
        解决风险预警
        """
        alert = self.get_object()
        alert.status = 'resolved'
        alert.resolved_at = timezone.now()
        alert.resolved_by = request.user
        alert.save()
        
        return Response({
            'message': '风险预警已解决',
            'alert_id': alert.id
        })
    
    @action(detail=True, methods=['post'])
    def ignore(self, request, pk=None):
        """
        忽略风险预警
        """
        alert = self.get_object()
        alert.status = 'ignored'
        alert.resolved_at = timezone.now()
        alert.resolved_by = request.user
        alert.save()
        
        return Response({
            'message': '风险预警已忽略',
            'alert_id': alert.id
        })


class RiskAssessmentResultViewSet(viewsets.ReadOnlyModelViewSet):
    """
    风险评估结果视图集（只读）
    """
    queryset = RiskAssessmentResult.objects.all()
    serializer_class = RiskAssessmentResultSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user = self.request.user
        
        # 普通用户只能查看自己的投资组合的评估结果
        if not user.is_staff:
            queryset = queryset.filter(portfolio__user=user)
        
        portfolio_id = self.request.query_params.get('portfolio_id')
        if portfolio_id:
            queryset = queryset.filter(portfolio_id=portfolio_id)
            
        return queryset
    
    @action(detail=False, methods=['post'])
    def generate_assessment(self, request):
        """
        生成风险评估报告
        """
        portfolio_id = request.data.get('portfolio_id')
        if not portfolio_id:
            return Response(
                {'error': '请提供投资组合ID'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # 调用风险计算服务
            risk_service = RiskCalculationService()
            assessment_result = risk_service.calculate_portfolio_risk(portfolio_id)
            
            serializer = self.get_serializer(assessment_result)
            return Response(serializer.data)
            
        except Exception as e:
            return Response(
                {'error': f'风险评估失败: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class RiskLimitViewSet(viewsets.ModelViewSet):
    """
    风险限额管理视图集
    """
    queryset = RiskLimit.objects.all()
    serializer_class = RiskLimitSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user = self.request.user
        
        # 普通用户只能查看自己的投资组合的限额
        if not user.is_staff:
            queryset = queryset.filter(portfolio__user=user)
        
        portfolio_id = self.request.query_params.get('portfolio_id')
        limit_type = self.request.query_params.get('limit_type')
        is_breached = self.request.query_params.get('is_breached')
        
        if portfolio_id:
            queryset = queryset.filter(portfolio_id=portfolio_id)
        if limit_type:
            queryset = queryset.filter(limit_type=limit_type)
        if is_breached is not None:
            queryset = queryset.filter(is_breached=is_breached.lower() == 'true')
            
        return queryset
    
    @action(detail=True, methods=['post'])
    def update_utilization(self, request, pk=None):
        """
        更新限额使用率
        """
        risk_limit = self.get_object()
        risk_limit.update_utilization()
        
        serializer = self.get_serializer(risk_limit)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get'])
    def breached_limits(self, request):
        """
        获取已突破的限额
        """
        queryset = self.get_queryset().filter(is_breached=True)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)


class RiskMonitoringTaskViewSet(viewsets.ModelViewSet):
    """
    风险监控任务视图集
    """
    queryset = RiskMonitoringTask.objects.all()
    serializer_class = RiskMonitoringTaskSerializer
    permission_classes = [IsAuthenticated, IsAdminUser]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        
        task_status = self.request.query_params.get('status')
        task_type = self.request.query_params.get('task_type')
        portfolio_id = self.request.query_params.get('portfolio_id')
        
        if task_status:
            queryset = queryset.filter(status=task_status)
        if task_type:
            queryset = queryset.filter(task_type=task_type)
        if portfolio_id:
            queryset = queryset.filter(portfolio_id=portfolio_id)
            
        return queryset
    
    @action(detail=True, methods=['post'])
    def execute(self, request, pk=None):
        """
        执行监控任务
        """
        task = self.get_object()
        
        if task.status != 'pending':
            return Response(
                {'error': '任务状态不允许执行'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # 调用风险监控服务
            monitoring_service = RiskMonitoringService()
            result = monitoring_service.execute_task(task)
            
            return Response({
                'message': '任务执行成功',
                'task_id': task.id,
                'result': result
            })
            
        except Exception as e:
            task.status = 'failed'
            task.error_message = str(e)
            task.save()
            
            return Response(
                {'error': f'任务执行失败: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def dashboard(self, request):
        """
        风险监控仪表板数据
        """
        # 统计各种状态的任务数量
        total_tasks = self.get_queryset().count()
        pending_tasks = self.get_queryset().filter(status='pending').count()
        running_tasks = self.get_queryset().filter(status='running').count()
        completed_tasks = self.get_queryset().filter(status='completed').count()
        failed_tasks = self.get_queryset().filter(status='failed').count()
        
        # 统计活跃的风险预警
        active_alerts = RiskAlert.objects.filter(status='active').count()
        high_risk_alerts = RiskAlert.objects.filter(
            status='active', 
            alert_level__in=['high', 'critical']
        ).count()
        
        # 统计突破的风险限额
        breached_limits = RiskLimit.objects.filter(is_breached=True).count()
        
        return Response({
            'task_statistics': {
                'total': total_tasks,
                'pending': pending_tasks,
                'running': running_tasks,
                'completed': completed_tasks,
                'failed': failed_tasks
            },
            'alert_statistics': {
                'active_alerts': active_alerts,
                'high_risk_alerts': high_risk_alerts
            },
            'limit_statistics': {
                'breached_limits': breached_limits
            }
        })